package com.shakespace.artofandroid.chapter02.custombinder

import android.os.IBinder
import android.os.IInterface
import android.os.Parcel
import com.shakespace.artofandroid.chapter02.Book
import com.shakespace.artofandroid.chapter02.custombinder.IBookManager2.Proxy.Companion.sDefaultImpl

// 2020-01-08 NOTE: create an file just like aidl do
interface IBookManager2 : IInterface {

    abstract class BookManager2Impl : android.os.Binder(), IBookManager2 {
        init {
            this.attachInterface(this, DESCRIPTOR)
        }

        override fun asBinder(): IBinder {
            return this
        }

        @Throws(android.os.RemoteException::class)
        public override fun onTransact(
            code: Int,
            data: Parcel,
            reply: Parcel?,
            flags: Int
        ): Boolean {
            val descriptor = DESCRIPTOR
            when (code) {
                IBinder.INTERFACE_TRANSACTION -> {
                    reply!!.writeString(descriptor)
                    return true
                }
                TRANSACTION_getBookList -> {
                    data.enforceInterface(descriptor)
                    val _result = bookList
                    reply!!.writeNoException()
                    reply.writeTypedList<Book>(_result)
                    return true
                }
                TRANSACTION_addBook -> {
                    data.enforceInterface(descriptor)
                    val _arg0: com.shakespace.artofandroid.chapter02.Book?
                    if (0 != data.readInt()) {
                        _arg0 = com.shakespace.artofandroid.chapter02.Book.createFromParcel(data)
                    } else {
                        _arg0 = null
                    }
                    if (_arg0 != null) {
                        this.addBook(_arg0)
                    }
                    reply!!.writeNoException()
                    return true
                }
                else -> {
                    return super.onTransact(code, data, reply, flags)
                }
            }
        }
    }

    private class Proxy internal constructor(private val mRemote: IBinder) :
        IBookManager2 {

        val interfaceDescriptor: String
            get() = DESCRIPTOR

        override fun asBinder(): IBinder {
            return mRemote
        }

        @Throws(android.os.RemoteException::class)
        override fun addBook(book: Book) {
            val _data = Parcel.obtain()
            val _reply = Parcel.obtain()
            try {
                _data.writeInterfaceToken(DESCRIPTOR)
                _data.writeInt(1)
                book.writeToParcel(_data, 0)
                val _status = mRemote.transact(TRANSACTION_addBook, _data, _reply, 0)
                if (!_status && defaultImpl != null) {
                    defaultImpl!!.addBook(book)
                    return
                }
                _reply.readException()
            } finally {
                _reply.recycle()
                _data.recycle()
            }
        }


        override val bookList: List<Book>
            @Throws(android.os.RemoteException::class)
            get() {
                val _data = Parcel.obtain()
                val _reply = Parcel.obtain()
                val _result: List<Book>
                try {
                    _data.writeInterfaceToken(DESCRIPTOR)
                    val _status = mRemote.transact(TRANSACTION_getBookList, _data, _reply, 0)
                    if (!_status && defaultImpl != null) {
                        return defaultImpl!!.bookList
                    }
                    _reply.readException()
                    _result = _reply.createTypedArrayList<Book>(Book)!!
                } finally {
                    _reply.recycle()
                    _data.recycle()
                }
                return _result
            }


        companion object {
            var sDefaultImpl: IBookManager2? = null
        }
    }

    companion object {
        private val DESCRIPTOR = "com.shakespace.artofandroid.IBookManager2"

        /**
         * Cast an IBinder object into an com.shakespace.artofandroid.IBookManager2 interface,
         * generating a proxy if needed.
         */
        fun asInterface(obj: IBinder?): IBookManager2? {
            if (obj == null) {
                return null
            }
            val iin = obj.queryLocalInterface(DESCRIPTOR)
            return if (iin != null && iin is IBookManager2) {
                iin
            } else Proxy(obj)
        }

        internal val TRANSACTION_getBookList = IBinder.FIRST_CALL_TRANSACTION + 0
        internal val TRANSACTION_addBook = IBinder.FIRST_CALL_TRANSACTION + 1

        val defaultImpl: IBookManager2?
            get() = sDefaultImpl
    }

    @Throws(android.os.RemoteException::class)
    fun addBook(book: Book)

    val bookList: List<Book>

}